// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3)
package br.unb.graphics;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;

import java.util.HashMap;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;

import br.unb.core.manager.Manager;
import br.unb.core.synchronism.Synchronism;
import br.unb.utils.Console;
import br.unb.utils.Resource;

public class SynchronismPanel extends JPanel {

    private static String server = "server";
    private static String client = "client";
    private static String wait = "wait";
    private static String sync = "sync";
    private static String precision = "precision";
    private static String high = "high";
    private static String medium = "medium";
    private static String low = "low";
    private static String waitingConf = "waitingConf";
    private static String confirmed = "confirmed";
    private static String stop = "stop";
    private static String resync = "resync";
    private static String syncAction = "syncAction";
    private static String waitSyncAction = "waitSyncAction";
    private static String stopAction = "stopAction";
    private static String resyncAction = "resyncAction";
    private static Dimension GAP = new Dimension(1, 1);
    private HashMap actionMap;
    private JTextField serverField, portField, clientField;
    private JRadioButton highRadio, mediumRadio, lowRadio;
    private ButtonGroup group;
    private JList waitingList, confirmedList;
    private Vector waitingVector, confirmedVector;
    private InterfaceFactory iFactory;
    private Action[] actions = {
        new SyncAction(),
        new ResyncAction(),
        new StopAction(),};

    public SynchronismPanel() {
        super(new BorderLayout());
        iFactory = new InterfaceFactory(Resource.Sync, actions);
        serverField = new JTextField(15);
        portField = new JTextField(6);
        clientField = new JTextField(15);

        //RadioButtons
        highRadio = iFactory.createRadioButton(high, false);
        mediumRadio = iFactory.createRadioButton(medium, false);
        lowRadio = iFactory.createRadioButton(low, false);

        group = new ButtonGroup();
        group.add(highRadio);
        group.add(mediumRadio);
        group.add(lowRadio);

        //Lists (TODO move this to core??)
        waitingList = new JList();
        waitingList.setPreferredSize(new Dimension(100, 180));
        waitingList.setBackground(Color.WHITE);
        waitingList.setCellRenderer(new ListRenderer(false));//Only File Objects
        waitingVector = new Vector();
        confirmedVector = new Vector();

        confirmedList = new JList();
        confirmedList.setPreferredSize(new Dimension(100, 180));
        confirmedList.setBackground(Color.WHITE);
        confirmedList.setCellRenderer(new ListRenderer(true));//Somente objetos do tipo File

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(this.getClienteServerPanel());
        add(this.getListsPanel());

    }

    private JPanel getClienteServerPanel() {

        JPanel mainPanel = new JPanel(),
                buttonPanel = new JPanel(),
                radioPanel = new JPanel();
        //, serverPanel = new JPanel(), clientPanel = new JPanel();

        GridBagLayout gbLayout = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();

        mainPanel.setLayout(gbLayout);

        gbc.insets = new Insets(1, 1, 1, 1);
        gbc.anchor = GridBagConstraints.WEST;

        gbc.gridy = 0;
        gbc.gridx = 0;
        mainPanel.add(iFactory.createLabel(server), gbc);
        gbc.gridx = 1;
        mainPanel.add(serverField, gbc);
        gbc.gridx = 2;
        mainPanel.add(portField, gbc);

        gbc.gridy = 1;
        gbc.gridx = 0;
        mainPanel.add(iFactory.createLabel(client), gbc);
        gbc.gridx = 1;
        mainPanel.add(clientField, gbc);

        gbc.gridy = 2;
        gbc.gridx = 0;
        mainPanel.add(iFactory.createLabel(precision), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.gridy = 2;
        gbc.gridx = 1;
        radioPanel.add(highRadio);
        radioPanel.add(mediumRadio);
        radioPanel.add(lowRadio);
        mainPanel.add(radioPanel, gbc);

        gbc.gridy = 3;
        gbc.gridx = 1;
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        buttonPanel.add(iFactory.createButton(sync));
        //buttonPanel.add(createButton(wait));
        mainPanel.add(buttonPanel, gbc);

        return mainPanel;
    }

    private JPanel getListsPanel() {
        JPanel mainPanel = new JPanel(),
                wLabelPanel = new JPanel(),
                cLabelPanel = new JPanel(),
                waitingPanel = new JPanel(),
                confirmedPanel = new JPanel(),
                buttonPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
        waitingPanel.setLayout(new BoxLayout(waitingPanel, BoxLayout.Y_AXIS));
        confirmedPanel.setLayout(new BoxLayout(confirmedPanel, BoxLayout.Y_AXIS));

        FlowLayout fl = new FlowLayout();
        fl.setAlignment(FlowLayout.LEFT);
        wLabelPanel.setLayout(fl);
        cLabelPanel.setLayout(fl);
        buttonPanel.setLayout(fl);

        wLabelPanel.add(iFactory.createLabel(waitingConf));
        waitingPanel.add(wLabelPanel);
        JScrollPane waitingScroll = new JScrollPane(waitingList);
        waitingScroll.setPreferredSize(new Dimension(100, 200));
        waitingPanel.add(waitingScroll);
        waitingPanel.add(Box.createRigidArea(new Dimension(2, 35)));

        cLabelPanel.add(iFactory.createLabel(confirmed));
        confirmedPanel.add(cLabelPanel);
        JScrollPane confirmedScroll = new JScrollPane(confirmedList);
        confirmedScroll.setPreferredSize(new Dimension(100, 200));

        confirmedPanel.add(confirmedScroll);

        buttonPanel.add(iFactory.createButton(stop));
        buttonPanel.add(iFactory.createButton(resync));
        confirmedPanel.add(buttonPanel);

        mainPanel.add(Box.createRigidArea(new Dimension(2, 2)));
        mainPanel.add(waitingPanel);
        mainPanel.add(Box.createRigidArea(new Dimension(2, 2)));
        mainPanel.add(confirmedPanel);

        return mainPanel;
    }

    public Synchronism.Precision getPrecision() {
        if (highRadio.isSelected()) {
            return Synchronism.Precision.HIGH;
        } else if (mediumRadio.isSelected()) {
            return Synchronism.Precision.MEDIUM;
        } else if (lowRadio.isSelected()) {
            return Synchronism.Precision.LOW;
        }
        return Synchronism.Precision.LOW;
    }

    /**
     * Adds a Synchronism to the waiting queue list
     * @param Synchronism
     */
    public void addToWaiting(Synchronism model) {
        this.waitingVector.add(model);
        this.waitingList.setListData(this.waitingVector);
        this.waitingList.repaint();
    }

    /**
     * Adds a Sincmodel to the confirmed queue list
     * @param file Objeto File que representa o arquivo
     */
    public void addToConfirmed(Synchronism model) {
        this.confirmedVector.add(model);
        this.confirmedList.setListData(this.confirmedVector);
        this.confirmedList.repaint();
    }

    /**
     * Returns a list of models already confirmed
     * @return vector (SincModels) List of models
     */
    public Vector getConfirmedSelecteds() {
        return this.confirmedVector;
    }

    /**
     * Removes a Synchronism from the waiting list
     * @param Synchronism
     */
    public void removeFromWaiting(Synchronism model) {
        this.waitingVector.remove(model);
        this.waitingList.setListData(this.waitingVector);
        this.waitingList.repaint();
    }

    public void confirm(Synchronism model) {
        this.removeFromWaiting(model);
        this.addToConfirmed(model);
    }

    /**
     * Remove a Synchronism from the confimed list
     * @param Synchronism
     */
    public void removeFromConfirmed(Synchronism model) {
        this.confirmedVector.remove(model);
        this.confirmedList.setListData(this.confirmedVector);
        this.confirmedList.repaint();
    }

    /****************************** Aux Classes ******************************/
    class ListRenderer extends JLabel implements ListCellRenderer {

        private boolean isConfirmed;

        ListRenderer(boolean isConfirmed) {
            this.isConfirmed = isConfirmed;
        }
        // This is the only method defined by ListCellRenderer.
        // We just reconfigure the JLabel each time we're called.

        public Component getListCellRendererComponent(
                JList list,
                Object value, // value to display
                int index, // cell index
                boolean isSelected, // is the cell selected
                boolean cellHasFocus) // the list and the cell have the focus
        {
            Synchronism model = (Synchronism) value;
            String s = "empty";
            if (model != null) {
                s =
                        "(C)" + model.getClientIp() + " >> " + "(S)" + model.getServerIp() + ":" + model.getPort() + (this.isConfirmed ? " (Offset=" + model.getOffset() + "us)" : "");
            }
            setText(s);

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            setEnabled(list.isEnabled());
            setFont(list.getFont());
            setOpaque(true);
            return this;
        }
        //TODO verify if Actions implementation could be moved from here!!
    }

    /*********************************************************************/
    /*********************         ACTIONS           *********************/
    /*********************************************************************/
    class SyncAction extends AbstractAction {

        SyncAction() {
            super(syncAction);
        }

        public void actionPerformed(ActionEvent e) {
            //SincButton Action
            int port = Integer.parseInt(portField.getText());
            if (port < 1025) {
                Console.showMessageDialog(Resource.getString("INVALID_PORT"));
            }
            Synchronism sync = new Synchronism(
                    clientField.getText(),
                    serverField.getText(),
                    port,
                    getPrecision());


            if (sync != null) {
                Manager.getInstance().handleSync(sync);
                int count = 0;
                while (true) {
                    sync = Manager.getInstance().getHandleSync();
                    if (sync != null) {
                        break;
                    }
                    count++;//kind of a time out;
                    if (count > 1000) {
                        break;
                    }
                }
            }
            GraphicInterface.getInstance().getSyncPanel().addToWaiting(sync);
        }
    }

    class StopAction extends AbstractAction {

        StopAction() {
            super(stopAction);
        }

        public void actionPerformed(ActionEvent e) {
            //Stop button Action
            for (int i = 0; i < confirmedVector.size(); i++) {
                Synchronism sync = (Synchronism) confirmedVector.get(i);
                if (sync != null) {
                    Manager.getInstance().stopSync(sync);
                    int count = 0;
                    while (true) {
                        sync = Manager.getInstance().getstopSync();
                        if (sync != null) {
                            break;
                        }
                        count++;//kind of a time out;
                        if (count > 1000) {
                            break;
                        }
                    }
                    GraphicInterface.getInstance().getSyncPanel().removeFromConfirmed(sync);
                }
            }
        }
    }

    class ResyncAction extends AbstractAction {

        ResyncAction() {
            super(resyncAction);
        }

        public void actionPerformed(ActionEvent e) {
            //Resync button action
            for (int i = 0; i < confirmedVector.size(); i++) {
                Synchronism sync = (Synchronism) confirmedVector.get(i);
                if (sync != null) {
                    Manager.getInstance().reSync(sync);
                    int count = 0;
                    while (true) {
                        sync = Manager.getInstance().getReSync();
                        if (sync != null) {
                            break;
                        }
                        count++;//kind of a time out;
                        if (count > 1000) {
                            break;
                        }
                    }
                    GraphicInterface.getInstance().getSyncPanel().removeFromConfirmed(sync);
                }
            }
        }
    }

    /* public static void main(String a[]){
    PanelChart pc = new PanelChart();
    System.out.println(pc.getResourceString("severLabel"));
    }*/
}
